---
title: MSMQ transaction lifecycle
summary: Manages an MSMQ transaction so multiple queued sends can be batched under one commit/abort.
status: draft
owner: SAIF Case Management
last_reviewed: 2026-08-21
library: SAIF.Services.Printing
reference_type: embedded
operation_id: OP-PRINT-MSMQ-TXN
trigger: Caller invokes clsPrint.StartMQTransaction / clsPrint.EndMQTransaction
---

# MSMQ transaction lifecycle

Manages the lifecycle of an MSMQ `MessageQueueTransaction`, allowing a caller to batch multiple queued document sends under a single commit or abort.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-PRINT-MSMQ-TXN |
| **Trigger** | Caller invokes `StartMQTransaction()` before one or more `distributeDocument` (asynchronous) calls, then `EndMQTransaction(inAction)` |
| **Inputs** | `inAction` (Boolean: commit vs. abort) for `EndMQTransaction` |
| **Outputs** | Committed or aborted `MessageQueueTransaction` |
| **Primary components** | `clsPrint.StartMQTransaction`, `clsPrint.EndMQTransaction` |
| **Entry point** | `SAIF.Services.Printing\clsPrint.vb` |

## Steps

1. `StartMQTransaction`: if no transaction is already started, creates a new `MessageQueueTransaction`, calls `Begin()`, and sets an internal "started" flag — allows a caller to batch multiple queued sends under one transaction before calling [Distribute a document](distribute-document.md).
2. `EndMQTransaction(inAction)`: if a transaction was started, commits (`inAction = True`) or aborts (`inAction = False`) it.
   - Always resets the "started" flag and disposes the transaction object in a `Finally` block, regardless of outcome.

## Process flow

```mermaid
flowchart TD
	Start([StartMQTransaction called]) --> Check{Transaction already started?}
	Check -->|No| Create[Create MessageQueueTransaction and Begin]
	Check -->|Yes| Reuse[Reuse existing transaction]
	Create --> Ready([Ready for queued sends])
	Reuse --> Ready
	Ready --> End([EndMQTransaction called])
	End --> Action{inAction?}
	Action -->|True| Commit[Commit transaction]
	Action -->|False| Abort[Abort transaction]
	Commit --> Dispose[Reset flag and dispose transaction]
	Abort --> Dispose
```

## Failure and edge-case behavior
- The transaction object is always disposed in a `Finally` block, so a transaction is never left open regardless of commit/abort outcome or an intervening exception.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `SAIF.Services.Printing\clsPrint.vb`
